#include "lvgl/lvgl.h"
#include <stdio.h>

#include "config/CustomConfig.h"
#include "assets/fonts/single_color_emoji.h"
#include "assets/fonts/chinese_font.h"
#include "../av_foundation/audio_play_ui.h"
#include <curl/curl.h>
#include "utils/network/http_client.h"
#include "utils/components/navigation_bar.h"

#include "../data_handle/data_handle.h"
#include "home.h"
#include "include/common.h"
#include "utils/components/sdl_disp_window.h"
#include "../lvgl_foundation/lvgl_components_ui.h"
#include "../third_partys/third_partys.h"

lv_obj_t *home_screen;  // 在.h通过extern声明home_screen但不分配内存，然后在.c文件即此处给home_screen分配内存
lv_display_t *home_disp;  // 在.h通过extern声明home_disp但不分配内存，然后在.c文件即此处给home_disp分配内存
#define ITEM_COUNT 19

// ✅emoji字符导入：
// "🏠"等emoji在label标签组件不显示，因为字体文件中没有这些Unicode字符。
// LVGL 默认使用的 lv_font_montserrat_20 是 内置的英文字体，
// 它只包含：ASCII（A–Z, a–z, 0–9, 符号）及少量扩展字符
// NotoColorEmoji-Regular.ttf下载地址：https://fonts.google.com/noto/specimen/Noto+Color+Emoji
// ❌NotoColorEmoji-Regular.ttf是「彩色位图字体」，LVGL 不支持，会显示空白；
// 得用单色字体Noto Emoji-Regular.ttf，步骤如下：
// 1️⃣打开终端，执行npm下载lv_font_conv工具指令：npm install -g lv_font_conv
// 2️⃣下载单色字体到DeskTop：https://www.fontmirror.com/app_public/files/t/22/2024/10/Noto%20Emoji-Regular.ttf
// 3️⃣终端执行：cd ~/Desktop，然后执行如下命令将指定的emoji字符
// 通过lv_font_conv工具及下载的单色字体"Noto Emoji-Regular.ttf"转换为C文件即生成LVGL字体文件，只包含指定的emoji字符：
// ❌注意需要加上--range 0x20-0x7F参数实现把英文、数字、标点等普通字符包括进去，否则没包括进去会导致字符显示不出来
/*
lv_font_conv --bpp 4 --size 16 \
  --no-compress --format lvgl \
  --font Noto\ Emoji-Regular.ttf \
  --range 0x20-0x7F \
  --symbols "🏠📁❓⚙️" \
  -o chinese_emoji.c
*/
// 5️⃣在label中使用emoji字符：
/*
  lv_obj_t *icon = lv_label_create(item);//创建label对象
  lv_label_set_text(icon, "🏠");//label标签设置emoji标题
  lv_obj_set_style_text_font(icon, &single_color_emoji, LV_PART_MAIN);//label标签设置emoji字符
  lv_obj_set_style_text_color(icon, lv_color_hex(0x128371), 0);//设置标签标题颜色即emoji颜色为lv_color_hex(0x128371)
*/

// ✅中文字符导入：
// 中文字符在label标签组件不显示，因为字体文件中没有这些Unicode字符。
// LVGL 默认使用的 lv_font_montserrat_20 是 内置的英文字体，
// 它只包含：ASCII（A–Z, a–z, 0–9, 符号）及少量扩展字符
// 具体步骤如下：
// 1️⃣打开终端，执行npm下载lv_font_conv工具指令：npm install -g lv_font_conv
// 2️⃣下载中文字体到DeskTop：NotoSansSC-Regular.otf下载地址：https://fontmeme.com/fonts/noto-sans-sc-font/
// 3️⃣终端执行：cd ~/Desktop，然后执行如下命令将指定的emoji字符
// 通过lv_font_conv工具及下载的中文字体"NotoSansSC-Regular.otf"转换为C文件即生成LVGL字体文件，只包含指定的中文字符：
// ❌注意需要加上--range 0x20-0x7F参数实现把英文、数字、标点等普通字符包括进去，否则没包括进去会导致字符显示不出来
/*
  lv_font_conv --bpp 4 --size 16 \
  --no-compress --format lvgl \
  --font NotoSansSC-Regular.otf \
  --range 0x20-0x7F \
  --symbols "你好世界" \
  -o chinese_font.c
*/
// 5️⃣在label中使用中文字符：
/*
  lv_obj_t *icon = lv_label_create(item);//创建label对象
  lv_label_set_text(icon, "你好世界");//label标签设置中文标题
  lv_obj_set_style_text_font(icon, &chinese_font, LV_PART_MAIN);//label标签设置中文字符
*/

// static全局变量只在当前.c文件可见，不会与其他.c文件发生重复的情况，否则重复情况会报错❌：duplicate symbol '_items' in:
// 即使全局变量只在.c文件声明而不是.h文件声明，也不能和其他.c文件的全局变量重复，否则会报错❌：duplicate symbol '_items' in:
// 💡 C 语言里，全局变量在没有 static 修饰时，是具有外部链接性（external linkage），会导出到整个目标文件的符号表中。
// 所以两个 .c 文件定义了相同名字的变量，就会“重复定义”。
static HomeItem items[ITEM_COUNT] = {
    {"🏠", "lvgl components"},
    {"📁", "data handle"},
    {"❓", "third_partys"},
    {"⚙️", "Settings"},
    {"⚙️", "Settings2"},
    {"⚙️", "Settings3"},
    {"⚙️", "Settings4"},
    {"⚙️", "Settings5"},
    {"⚙️", "Settings6"},
    {"⚙️", "Settings7"},
    {"⚙️", "Settings8"},
    {"⚙️", "Settings9"},
    {"⚙️", "Settings10"},
    {"⚙️", "Settings11"},
    {"⚙️", "Settings12"},
    {"⚙️", "Settings13"},
    {"⚙️", "Settings14"},
    {"⚙️", "Settings15"},
    {"⚙️", "Settings16"}
};

/* 点击事件回调
加上 static → 限制作用域，防止外部文件访问
*/
static void item_event_cb(lv_event_t * e)
{
    int click_index = (int)(intptr_t)lv_event_get_user_data(e);  // ✅ 从 user_data 获取索引
    const char *text = items[click_index].text;
    printf("Clicked item at: %d %s\n", click_index, text);
    switch (click_index)
    {
    case 0:
        lvgl_components_ui();
        break;
    case 1:
        data_handle_ui();
        break;
    case 2:
        third_partys_ui();
        break;
    default:
        break;
    }
    // 获取项目当前LVGL版本，LVGL version: 9.4.0
    // printf("LVGL version: %d.%d.%d\n", LVGL_VERSION_MAJOR, LVGL_VERSION_MINOR, LVGL_VERSION_PATCH);
}

/* 页面初始化数据：负责加载数据并更新 UI，例如从文件读取配置、设置滑块初始值、填充文本等。
*/
void init_home_page() {

}

/* 创建 Home 界面
// ✅职责分离：lv_home_ui()本质上是构建UI，不负责数据来源和逻辑。如果直接在它内部调用init_home_page()，
// 就把数据逻辑混进 UI 创建逻辑里，未来测试或重置UI时会麻烦。
// 可扩展性：有时候可能只想创建UI，不立即加载文件。或者数据来源变了（从文件改为网络或缓存），这样就得改UI创建函数，耦合度高。
// 调用顺序安全：init_home_page()必须在UI组件创建之后调用，否则会访问空指针或未创建的子对象。
*/
void lv_home_ui(void)
{
    /* 创建一个滚动页面容器 */
    // 通过lv_obj_create()方法在lv_scr_act()当前活动屏幕创建一个基础对象（容器），这个容器可以包含子对象（比如按钮、标签等）。
    // 返回值(list)是一个指向这个新建对象的指针。
    // lv_obj_t * list = lv_obj_create(lv_scr_act());
    lv_obj_t * list = lv_obj_create(home_screen);//在home_screen主屏幕创建
    //设置这个容器的宽和高
    lv_obj_set_size(list, DISP_WIDTH, DISP_HEIGHT);
    //设置容器的滚动方向，LV_DIR_VER 表示“垂直方向可滚动”，如果内容超出容器高度，就可以上下滚动。
    lv_obj_set_scroll_dir(list, LV_DIR_VER);
    //设置容器上下左右的内边距8像素，最后一个参数 0 是样式选择器，0 表示默认状态；
    lv_obj_set_style_pad_all(list, 8, 0);
    //设置容器的背景颜色，最后一个参数0 是样式选择器，0表示默认状态。
    lv_obj_set_style_bg_color(list, lv_color_hex(0xfafafa), 0);
    // 设置 flex 布局，垂直排列
    lv_obj_set_flex_flow(list, LV_FLEX_FLOW_COLUMN);
    lv_obj_set_style_pad_row(list, 8, 0);   // 子对象垂直间距

    for (int i = 0; i < ITEM_COUNT; i++) {
        /* 在容器list内创建一个 item 按钮对象 */
        lv_obj_t *item = lv_btn_create(list);
        //设置对象item的宽度为父容器的 100%；高度固定为 60 像素。
        lv_obj_set_size(item, lv_pct(100), 60);
        //背景色
        lv_obj_set_style_bg_color(item, lv_color_hex(0xffffff), 0);
        //圆角 8px
        lv_obj_set_style_radius(item, 8, 0);
        //内边距 10px
        lv_obj_set_style_pad_all(item, 10, 0);
        //阴影宽度 5px
        lv_obj_set_style_shadow_width(item, 5, 0);
        //透明度 20%
        lv_obj_set_style_shadow_opa(item, LV_OPA_20, 0);

        /* icon */
        //在按钮上创建一个图标标签
        lv_obj_t *icon = lv_label_create(item);
        //设置标题
        lv_label_set_text(icon, items[i].icon);
        lv_obj_set_style_text_font(icon, &single_color_emoji, LV_PART_MAIN);
        lv_obj_set_style_text_color(icon, lv_color_hex(0x128371), 0);
        //设置左边与父视图左中对齐
        lv_obj_align(icon, LV_ALIGN_LEFT_MID, 0, 0);

        /* label */
        //在按钮上创建一个图标标签
        lv_obj_t *label = lv_label_create(item);
        //设置标题
        lv_label_set_text(label, items[i].text);
        //设置该对象整体与icon对象的右边距离10px
        lv_obj_align_to(label, icon, LV_ALIGN_OUT_RIGHT_MID, 10, 0);
        //普通字符使用 lv_font_montserrat_20，字号 20。
        //中文字符则需要自己导入，此处使用自行导入的中文字符集chinese_font（需包含英文数字等常用字符）
        lv_obj_set_style_text_font(label, &chinese_font, 0);
        //lv_obj_set_style_text_color设置字体颜色，lv_color_hex(0xfafafa)初始化颜色结构体lv_color_t
        lv_obj_set_style_text_color(label, lv_color_hex(0x128371), 0);

        /* 点击回调
        //Q: ✅C语言编译顺序问题：
        报错：❌error: use of undeclared identifier 'item_event_cb'
        108 | lv_obj_add_event_cb(item, item_event_cb, LV_EVENT_CLICKED, label);
        ✅原因分析：函数必须在使用前声明或定义即提前声明函数，否则编译器不知道这个函数的类型和参数，因此item_event_cb事件方法必须写在上面
        */
        //Q: int传参指针类型：最后一个参数是一个void *user_data指针，int值类型需采用(void *)转换成是一个指针类型，
        // 用intptr_t/uintptr_t可确保在32/64位平台上安全转换
        lv_obj_add_event_cb(item, item_event_cb, LV_EVENT_CLICKED, (void *)(intptr_t)i);

        /* 添加间距 */
        //给 list 容器的底部留 8 像素的间距；
        lv_obj_set_style_pad_bottom(list, 8, 0);
    }


}
